package es.ucm.fdi.xtremeaudio.vista;

import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLFrameHyperlinkEvent;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

import es.ucm.fdi.xtremeaudio.controlador.Controlador;

/**
 * <ul>
 * <li><b>Proyecto:</b> XtremeAudio</li>
 * <li><b>Grupo:</b> 7 <i>(4&deg;B)</i></li>
 * <li><b>Asignatura:</b> Ingenier&iacute;a del Software</li>
 * <li><b>Curso:</b> 2010/2011</li>
 * <li><b>Centro:</b> Universidad Complutense de Madrid</li>
 * </ul>
 * 
 * El <b>FormAyuda</b> es el formulario de ayuda de usuario en HTML que se
 * muestra al pulsar el bot&oacute;n adecuado del {@link FormPrincipal}. Puede
 * moverse por la pantalla y minimizarse.<br/>
 * <p>
 * <i><b>NOTA:</b> Omitimos los comentarios sobre los distintos componentes y
 * nos limitamos a comentar los m&eacute;todos relevantes</i>.<br/>
 * 
 * <i><b>NOTA:</b> Por problemas con compatibilidad entre {@link JTextPane} y
 * {@link JEditorPane} con HTML, el contenido de la ayuda puede visualizarse de
 * forma incorrecta al no tratar adecuadamente los estilos CSS. Como
 * soluci&oacute;n temporal, ejecutamos una rutina que abre la misma ayuda en
 * formato PDF (v&eacute;ase {@link Runtime#exec(String)})</i>.
 * </p>
 * 
 * @author &Aacute;lvaro G&oacute;mez Porris
 * @author Elena Hern&aacute;ndez Delgado
 * @author Mar&iacute;a Trinidad Mart&iacute;n Campos
 * @author Mois&eacute;s Mart&iacute;nez Montes
 * @author Mat&iacute;as Salinero Delgado
 * 
 * @version %I%, %G%
 * 
 * @since 1.0
 */
public class FormAyuda {

	private static Integer alto;
	private static Integer ancho;
	private JButton botonCerrar;
	private JButton botonMin;
	private JLabel labelTitulo;
	private JTextPane panelHTML;
	private JPanelImagen panelSuperior;
	private JPanel panelVentana;
	private JScrollPane scrollPaneHTML;
	private JFrame ventana;

	/**
	 * Constructora por defecto.
	 */
	public FormAyuda() {
		initLookAndFeel();
		initComponents();
	}

	/**
	 * 
	 * @return El bot&oacute;n.
	 */
	public JButton getBotonCerrar() {
		return botonCerrar;
	}

	/**
	 * 
	 * @return El bot&oacute;n.
	 */
	public JButton getBotonMin() {
		return botonMin;
	}

	/**
	 * 
	 * @return La etiqueta.
	 */
	public JLabel getLabelTitulo() {
		return labelTitulo;
	}

	/**
	 * 
	 * @return El panel.
	 */
	public JTextPane getPanel() {
		return panelHTML;
	}

	/**
	 * 
	 * @return El panel.
	 */
	public JTextPane getPanelHTML() {
		return panelHTML;
	}

	/**
	 * 
	 * @return El panel con imagen.
	 */
	public JPanelImagen getPanelSuperior() {
		return panelSuperior;
	}

	/**
	 * 
	 * @return El panel.
	 */
	public JPanel getPanelVentana() {
		return panelVentana;
	}

	/**
	 * 
	 * @return El scroll.
	 */
	public JScrollPane getScrollPaneHTML() {
		return scrollPaneHTML;
	}

	/**
	 * 
	 * @return La ventana.
	 */
	public JFrame getVentana() {
		return ventana;
	}

	/**
	 * Oculta la ventana.
	 */
	public void hide() {
		ventana.setVisible(false);
	}

	/**
	 * 
	 * @param botonCerrar
	 */
	public void setBotonCerrar(JButton botonCerrar) {
		this.botonCerrar = botonCerrar;
	}

	/**
	 * 
	 * @param botonMin
	 */
	public void setBotonMin(JButton botonMin) {
		this.botonMin = botonMin;
	}

	/**
	 * 
	 * @param labelTitulo
	 */
	public void setLabelTitulo(JLabel labelTitulo) {
		this.labelTitulo = labelTitulo;
	}

	/**
	 * 
	 * @param panelHTML
	 */
	public void setPanel(JTextPane panelHTML) {
		this.panelHTML = panelHTML;
	}

	/**
	 * 
	 * @param panelHTML
	 */
	public void setPanelHTML(JTextPane panelHTML) {
		this.panelHTML = panelHTML;
	}

	/**
	 * 
	 * @param panelSuperior
	 */
	public void setPanelSuperior(JPanelImagen panelSuperior) {
		this.panelSuperior = panelSuperior;
	}

	/**
	 * 
	 * @param panelVentana
	 */
	public void setPanelVentana(JPanel panelVentana) {
		this.panelVentana = panelVentana;
	}

	/**
	 * 
	 * @param scrollPaneHTML
	 */
	public void setScrollPaneHTML(JScrollPane scrollPaneHTML) {
		this.scrollPaneHTML = scrollPaneHTML;
	}

	/**
	 * 
	 * @param ventana
	 */
	public void setVentana(JFrame ventana) {
		this.ventana = ventana;
	}

	/**
	 * Muestra el panel de ayuda con un tama&ntilde;o proporcional al de la
	 * pantalla.<br/>
	 * <i><b>NOTA:</b> Por problemas con compatibilidad entre {@link JTextPane}
	 * y {@link JEditorPane} con HTML, el contenido de la ayuda puede
	 * visualizarse de forma incorrecta al no tratar adecuadamente los estilos
	 * CSS. Como soluci&oacute;n temporal, ejecutamos una rutina que abre la
	 * misma ayuda en formato PDF (v&eacute;ase {@link Runtime#exec(String)}
	 * )</i>.
	 */
	public void show() {
		try {
			Runtime.getRuntime().exec(
					"rundll32 url.dll,FileProtocolHandler "
							+ "doc\\help\\pdf\\Ayuda.pdf");
		} catch (IOException e) {
			e.printStackTrace();
		}
		ventana.setVisible(true);
	}

	/*--- MÉTODOS PRIVADOS ---*/
	private void initComponents() {
		ventana = new JFrame();
		panelVentana = new JPanel();
		panelSuperior = new JPanelImagen("img/fondo_1100x60.png");
		labelTitulo = new JLabel();
		botonMin = new JButton();
		botonCerrar = new JButton();
		scrollPaneHTML = new JScrollPane();
		panelHTML = new JTextPane();
		try {
			/*
			 * StyleSheet style = new StyleSheet();
			 * style.importStyleSheet(FormAyuda.class.getClassLoader()
			 * .getResource("doc/help/html/estiloReproductor.css"));
			 * DefaultStyledDocument docS = new DefaultStyledDocument(style);
			 * panelHTML = new JTextPane(docS); StyledEditorKit kit =
			 * ((StyledEditorKit) panelHTML.getEditorKit()); Document doc =
			 * kit.createDefaultDocument(); panelHTML.setDocument(doc);
			 */
			panelHTML.setContentType("text/html");
			panelHTML.setPage(FormAyuda.class.getClassLoader().getResource(
					"doc/help/html/Ayuda.html"));

		} catch (IOException e) {
			e.printStackTrace();
		}

		/*--- DIMENSIONES DE PANELES EN FUNCION DE LA PANTALLA ---*/
		// w->width, h->height
		final Integer wPVentana, wPSuperior, wPHTML;
		final Integer hPVentana, hPSuperior, hPHTML;
		final String sWPVentana, sWPSuperior, sWPHTML;
		final String sHPVentana, sHPSuperior, sHPHTML;
		Integer wIzq, wDer, hSup, hInf; // Auxiliares

		// 0: Panel Ventana
		wPVentana = ancho;
		sWPVentana = wPVentana.toString() + "dlu";

		hPVentana = alto;
		hSup = new Integer((int) (hPVentana * 0.15)); // Panel superior
		hInf = new Integer((int) (hPVentana * 0.85)); // Panel HTML
		sHPVentana = hSup.toString() + "dlu," + hInf.toString() + "dlu";

		// 1a: Panel Superior
		wPSuperior = wPVentana;
		wIzq = new Integer((int) (wPSuperior * 0.88)); // Logo
		wDer = new Integer((int) ((wPSuperior * 0.1) / 2)); // Tres botones
		sWPSuperior = wIzq.toString() + "dlu," + wDer.toString() + "dlu,"
				+ wDer.toString() + "dlu";

		hPSuperior = hSup;
		sHPSuperior = hPSuperior.toString() + "dlu";

		// 1b: Panel HTML
		wPHTML = wPVentana;
		sWPHTML = wPHTML.toString() + "dlu";

		hPHTML = hInf;
		sHPHTML = hPHTML.toString() + "dlu";

		// ======= Ventana =======
		ventana.setUndecorated(true); // Quita los botones del borde
		ventana.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
		ventana.setAlwaysOnTop(false);
		ventana.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Image icono = Toolkit.getDefaultToolkit().getImage(
				FormAyuda.class.getClassLoader().getResource(
						"img/iconoX_27x27.png"));
		ventana.setIconImage(icono);
		ventana.setTitle("Ayuda - XtremeAudio");
		Container ventanaContentPane = ventana.getContentPane();
		ventanaContentPane.setBackground(Color.black);
		ventanaContentPane.setLayout(new FormLayout(ancho.toString() + "dlu",
				alto.toString() + "dlu"));

		// ======== panelVentana ========
		{
			MoverPanelListener mml = new MoverPanelListener(panelVentana);
			panelVentana.addMouseListener(mml);
			panelVentana.addMouseMotionListener(mml);
			panelVentana
					.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
			panelVentana.setBackground(Color.black);
			panelVentana.setBorder(new LineBorder(new Color(255, 157, 92), 2,
					true));
			panelVentana.setLayout(new FormLayout(sWPVentana, sHPVentana));

			// ======== panelSuperior ========
			{
				panelSuperior.setBackground(new Color(255, 102, 0));
				panelSuperior.setBorder(new LineBorder(new Color(255, 157, 92),
						2, true));
				panelSuperior
						.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
				panelSuperior
						.setLayout(new FormLayout(sWPSuperior, sHPSuperior));

				// ---- labelTitulo ----
				labelTitulo.setIcon(new ImageIcon(FormAyuda.class
						.getClassLoader().getResource(
								"img/logoAyuda_350x50.png")));
				labelTitulo
						.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
				labelTitulo.setFocusable(false);
				panelSuperior.add(labelTitulo, new CellConstraints(1, 1, 1, 1,
						CellConstraints.CENTER, CellConstraints.TOP,
						new Insets(5, 0, 0, 0)));

				// ---- botonMin ----
				botonMin.setIcon(new ImageIcon(FormAyuda.class.getClassLoader()
						.getResource("img/minimizar_45x45.png")));
				botonMin.setCursor(Cursor
						.getPredefinedCursor(Cursor.HAND_CURSOR));
				botonMin.setBackground(Color.black);
				botonMin.setToolTipText("Minimizar");
				botonMin.setFocusable(false);
				botonMin.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
				botonMin.addActionListener(new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent e) {
						botonMinActionPerformed(e);
					}

					private void botonMinActionPerformed(ActionEvent e) {
						Controlador.minimizarFormAyuda();
					}
				});
				panelSuperior.add(botonMin, new CellConstraints(2, 1, 1, 1,
						CellConstraints.CENTER, CellConstraints.TOP,
						new Insets(2, 0, 0, 0)));

				// ---- botonCerrar ----
				botonCerrar.setIcon(new ImageIcon(FormAyuda.class
						.getClassLoader().getResource("img/cerrar_45x45.png")));
				botonCerrar.setCursor(Cursor
						.getPredefinedCursor(Cursor.HAND_CURSOR));
				botonCerrar.setBackground(Color.black);
				botonCerrar.setToolTipText("Salir");
				botonCerrar.setFocusable(false);
				botonCerrar
						.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
				botonCerrar.addActionListener(new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent e) {
						botonCerrarActionPerformed(e);
					}

					private void botonCerrarActionPerformed(ActionEvent e) {
						Controlador.cerrarFormAyuda();
					}
				});
				panelSuperior.add(botonCerrar, new CellConstraints(3, 1, 1, 1,
						CellConstraints.CENTER, CellConstraints.TOP,
						new Insets(2, 0, 0, 0)));
			}
			panelVentana.add(panelSuperior, new CellConstraints(1, 1, 1, 1,
					CellConstraints.FILL, CellConstraints.FILL, new Insets(3,
							2, 3, 6)));

			// ======== scrollPaneHTML ========
			{
				scrollPaneHTML.setBorder(null);
				scrollPaneHTML
						.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
				scrollPaneHTML
						.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
				scrollPaneHTML
						.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
				scrollPaneHTML.setViewportBorder(null);

				// ======== panelHTML ========
				{
					panelHTML.setBackground(new Color(255, 102, 0));
					panelHTML.setBorder(new LineBorder(new Color(255, 157, 92),
							2, true));
					panelHTML
							.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
					panelHTML.setEditable(false);
					panelHTML.setContentType("text/html");

					// Listener para seguir hipervinculos
					panelHTML.addHyperlinkListener(new HyperlinkListener() {
						@Override
						public void hyperlinkUpdate(HyperlinkEvent e) {
							if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
								JTextPane pane = (JTextPane) e.getSource();
								if (e instanceof HTMLFrameHyperlinkEvent) {
									HTMLDocument doc = (HTMLDocument) pane
											.getDocument();
									doc.processHTMLFrameHyperlinkEvent((HTMLFrameHyperlinkEvent) e);
								} else {
									try {
										pane.setPage(e.getURL());
										scrollPaneHTML.setViewportView(pane);
									} catch (Throwable t) {
										t.printStackTrace();
									}
								}
							}
						}
					});
					panelHTML.setLayout(new FormLayout(sWPHTML, sHPHTML));
				}
				scrollPaneHTML.setViewportView(panelHTML);
			}
			panelVentana.add(scrollPaneHTML, new CellConstraints(1, 2, 1, 1,
					CellConstraints.FILL, CellConstraints.FILL, new Insets(1,
							2, 4, 6)));
		}
		ventanaContentPane.add(panelVentana, new CellConstraints(1, 1, 1, 1,
				CellConstraints.FILL, CellConstraints.FILL));
		ventana.pack();
		ventana.setLocationRelativeTo(null);
	}

	private void initLookAndFeel() {
		// Establece el Look&Feel
		UIManager.put("nimbusBase", new Color(245, 94, 0));
		try {
			for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
				if ("Nimbus".equals(info.getName())) {
					UIManager.setLookAndFeel(info.getClassName());
					break;
				}
			}
		} catch (Exception e) {
			try {
				UIManager.setLookAndFeel(UIManager
						.getSystemLookAndFeelClassName());
			} catch (ClassNotFoundException e1) {
				e1.printStackTrace();
			} catch (InstantiationException e1) {
				e1.printStackTrace();
			} catch (IllegalAccessException e1) {
				e1.printStackTrace();
			} catch (UnsupportedLookAndFeelException e1) {
				e1.printStackTrace();
			}
		}

		// Obtiene las dimensiones de la pantalla
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		if (((float) screen.width / (float) screen.height) > 1.25) { // Panorámica
			ancho = new Integer((int) (screen.width / 2.8));
			alto = new Integer((int) (screen.height / 2.8));
		} else {
			ancho = new Integer((int) (screen.width / 2.8));
			alto = new Integer((int) (screen.height / 3.5));
		}
	}

}
